<?php

namespace App\Services\Impl;

use App\Constants\SystemEventTypeEnum;
use App\Entity\Bo\ReportEventBo;
use App\Factory\ReportServiceFactory;
use App\Model\Business\AppChannelReportConfig;
use App\Model\Business\Application;
use App\Model\Business\ChannelCode;
use App\Model\Report\BehaviorReport;
use App\Model\Report\BigDevice;
use App\Model\Report\BigDeviceEvent;
use Carbon\Carbon;

class ReportService
{
    private array $defaultReportConfigAry = [
        // 关键行为回传阈值，为0则不回传
        'cpm_complete'      => 0,
        // 激活上报方案
        'active_plan'       => 1,
        'delay_active_cpm'  => 0,
        'key_ary'           => [],
        // 标识本方法返回出去的是不是默认值，为 false 表示取的库返回，为 true 表示默认值返回
        'is_default_return' => true,
    ];

    public function reportLaunch($projectId, $appId, $channel, $version, $oaid)
    {
        $ascribeChannelType = ChannelCode::findChannelTypeByChannel($channel);
        $ascribeChannel     = $channel;

        $bigDevice = BigDevice::findDevice($appId, $oaid);
        if ($bigDevice) {
            $ascribeChannelType = $bigDevice->channel_type;
            $ascribeChannel     = $bigDevice->channel;
        }

        $reportService = ReportServiceFactory::createService($ascribeChannelType);
        $reportService->reportLaunch($appId, $oaid);

        $this->behaviorReportLogic($projectId, $appId, $channel, $version, $ascribeChannelType, $ascribeChannel,
            $oaid, SystemEventTypeEnum::LAUNCH);
    }

    public function reportEvent($appId, $channel, $version, $oaid, $systemEventType, $model)
    {
        $bigDevice = BigDevice::findDevice($appId, $oaid);
        throw_error_if(!$bigDevice, "没有设备信息");

        $app = Application::findOrFail($appId);

        $ascribeChannel = $bigDevice->channel;

        $ascribeChannelType = ChannelCode::findChannelTypeByChannel($ascribeChannel);

        $reportEventBo = new ReportEventBo();
        $reportEventBo->setProjectId($bigDevice->project_id);
        $reportEventBo->setAppId($appId);
        $reportEventBo->setApp($app);
        $reportEventBo->setChannel($channel);
        $reportEventBo->setVersion($version);
        $reportEventBo->setOaid($oaid);
        $reportEventBo->setBigDevice($bigDevice);
        $reportEventBo->setEventType($systemEventType);

        $reportService = ReportServiceFactory::createService($ascribeChannelType);
        $reportService->reportEvent($reportEventBo);
    }

    public function getChannelReportConfig($appId, $channel): array
    {
        // 取上报方案配置
        $channelReportConfig = AppChannelReportConfig::query()
            ->where('app_id', $appId)
            ->where('channel', $channel)
            ->first();
        if (!$channelReportConfig) {
            return $this->defaultReportConfigAry;
        }

        return [
            'cpm_complete'     => $channelReportConfig->cpm_complete,
            'active_plan'      => $channelReportConfig->active_plan,
            'delay_active_cpm' => $channelReportConfig->delay_active_cpm,
            'key_ary'          => $channelReportConfig->key_type,
        ];
    }

    /**
     * 行为事件上报
     */
    public function behaviorReportLogic($projectId, $appId, $channel, $version, $ascribeChannelType,
                                        $ascribeChannel, $oaid, $eventType): void
    {
        $channelType = ChannelCode::findChannelTypeByChannel($channel);

        $bigDevice = BigDevice::findDevice($appId, $oaid);

        BehaviorReport::create([
            'project_id'           => $projectId,
            'app_id'               => $appId,
            'channel_type'         => $channelType,
            'channel'              => $channel,
            'version'              => $version,
            'ascribe_channel_type' => $ascribeChannelType,
            'ascribe_channel'      => $ascribeChannel,
            'oaid'                 => $oaid,
            'ip'                   => '',
            'plan_id'              => $bigDevice->plan_id ?? '',
            'plan_name'            => $bigDevice->plan_name ?? '',
            'ad_id'                => $bigDevice->ad_id ?? '',
            'ad_name'              => $bigDevice->ad_name ?? '',
            'event_type'           => $eventType,
            'date'                 => Carbon::today()->toDateString()
        ]);
    }
}